package ws

import (
	"encoding/json"
	"log"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"github.com/gorilla/websocket"
)

// 定义消息结构体
// 添加文件信息结构体
type FileInfo struct {
	Name string `json:"Name"`
	Size int    `json:"Size"`
	Type string `json:"Type"`
	URL  string `json:"URL"`
}

// 扩展消息结构体，添加文件信息字段
type Message struct {
	Sender    string    `json:"sender"`
	SenderId  string    `json:"sender_id,omitempty"`
	Recipient string    `json:"recipient,omitempty"` // 可选，指定接收者
	Content   string    `json:"content"`
	Type      string    `json:"type"` // 消息类型：text, image等
	Timestamp int64     `json:"timestamp"`
	FileInfo  *FileInfo `json:"fileInfo,omitempty"` // 可选，文件信息
	Offset    int       `json:"offset,omitempty"`   // 分页偏移量
	Limit     int       `json:"limit,omitempty"`    // 分页限制
	MsgList   []Message `json:"msgList,omitempty"`
}

type SearchDateMessage struct {
	Message `json:",inline"`
	Date    string `json:"date"` // 搜索日期，毫秒级时间戳
}

type SearchFileTypeMessage struct {
	Message  `json:",inline"`
	FileType string `json:"fileType"` // 文件类型：image, video, audio等
}

type Response struct {
	Code int         `json:"code"` // 状态码，0表示成功
	Data interface{} `json:"data"` // 响应数据
	Msg  string      `json:"msg"`  // 响应消息
}

// 客户端连接
type Client struct {
	ID       string
	Conn     *websocket.Conn
	Send     chan []byte
	Manager  *Manager
	Username string
}

// WebSocket管理器
type Manager struct {
	Clients           map[string]*Client
	Register          chan *Client
	Unregister        chan *Client
	Broadcast         chan []byte
	SendPrivate       chan []byte
	HistoryPrivate    chan []byte
	SearchPrivate     chan []byte
	mutex             sync.Mutex
	MessageHandler    func(message []byte, client *Client) error
	HistoryHandler    func(offset, limit int) ([]Message, error)
	SearchDateHandler func(searchDate string, offset, limit int) ([]Message, error)
}

// 创建新的WebSocket管理器
func NewManager() *Manager {
	return &Manager{
		Clients:        make(map[string]*Client),
		Register:       make(chan *Client),
		Unregister:     make(chan *Client),
		Broadcast:      make(chan []byte),
		SendPrivate:    make(chan []byte),
		HistoryPrivate: make(chan []byte),
		SearchPrivate:  make(chan []byte),
		// 初始化MessageHandler为空函数，后续通过SetMessageHandler设置
		MessageHandler: func([]byte, *Client) error { return nil },
	}
}

// 启动管理器
func (manager *Manager) Start() {
	for {
		select {
		case client := <-manager.Register:
			manager.mutex.Lock()
			manager.Clients[client.ID] = client
			manager.mutex.Unlock()
			log.Printf("客户端已连接: %s", client.ID)

		case client := <-manager.Unregister:
			if _, ok := manager.Clients[client.ID]; ok {
				manager.mutex.Lock()
				delete(manager.Clients, client.ID)
				manager.mutex.Unlock()
				close(client.Send)
				log.Printf("客户端已断开: %s", client.ID)
			}

		case message := <-manager.Broadcast:
			// 广播消息
			manager.mutex.Lock()
			var msg Message
			if err := json.Unmarshal(message, &msg); err != nil {
				log.Println("解析广播消息失败:", err)
				manager.mutex.Unlock()
				continue
			}
			res := Response{
				Code: 0,
				Data: msg,
				Msg:  "success",
			}

			resJson, err := json.Marshal(res)
			if err != nil {
				log.Println("序列化响应失败:", err)
				manager.mutex.Unlock()
				continue
			}
			for _, client := range manager.Clients {
				if msg.SenderId != client.ID {
					select {
					case client.Send <- resJson:
					default:
						close(client.Send)
						delete(manager.Clients, client.ID)
					}
				}
			}
			manager.mutex.Unlock()

		case message := <-manager.SendPrivate:
			// 处理私有消息
			var msg Message
			if err := json.Unmarshal(message, &msg); err != nil {
				log.Println("解析私有消息失败:", err)
				continue
			}

			manager.mutex.Lock()
			if recipient, ok := manager.Clients[msg.Recipient]; ok {
				select {
				case recipient.Send <- message:
					log.Printf("已发送私有消息: %s -> %s", msg.Sender, msg.Recipient)
				default:
					close(recipient.Send)
					delete(manager.Clients, msg.Recipient)
				}
			}
			manager.mutex.Unlock()
		case historyMsg := <-manager.HistoryPrivate:
			// 处理获取历史记录请求(只会发给自己)
			var msg Message
			if err := json.Unmarshal(historyMsg, &msg); err != nil {
				log.Println("解析获取历史记录请求失败:", err)
				continue
			}
			res := Response{
				Code: 0,
				Data: msg,
				Msg:  "success",
			}
			historyMsg, err := json.Marshal(res)
			if err != nil {
				log.Println("序列化响应失败:", err)
				continue
			}

			if msg.Offset < 0 || msg.Limit <= 0 {
				log.Println("无效的分页参数")
				continue
			}
			if recipient, ok := manager.Clients[msg.Recipient]; ok {
				select {
				case recipient.Send <- historyMsg:
					log.Printf("已发送获取历史记录请求: %s -> %s", msg.Sender, msg.Recipient)
				default:
					close(recipient.Send)
					delete(manager.Clients, msg.Recipient)
				}
			}
		case searchDateMsg := <-manager.SearchPrivate:
			// 处理搜索日期消息
			var msg SearchDateMessage
			if err := json.Unmarshal(searchDateMsg, &msg); err != nil {
				log.Println("解析搜索日期消息失败:", err)
				continue
			}
			res := Response{
				Code: 0,
				Data: msg,
				Msg:  "success",
			}
			searchDateMsg, err := json.Marshal(res)
			if err != nil {
				log.Println("序列化响应失败:", err)
				continue
			}
			if msg.Offset < 0 || msg.Limit <= 0 {
				log.Println("无效的分页参数")
				continue
			}
			if recipient, ok := manager.Clients[msg.Recipient]; ok {
				select {
				case recipient.Send <- searchDateMsg:
					log.Printf("已发送搜索日期消息: %s -> %s", msg.Sender, msg.Recipient)
				default:
					close(recipient.Send)
					delete(manager.Clients, msg.Recipient)
				}
			}
		}

	}
}

func SetupSignalHandler(manager *Manager) {
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-c
		log.Println("接收到退出信号，正在清理...")
		// 关闭所有客户端连接
		manager.mutex.Lock()
		for _, client := range manager.Clients {
			client.Conn.Close()
			close(client.Send)
		}
		manager.mutex.Unlock()
		log.Println("清理完成，退出程序")
		syscall.Exit(0)
	}()
}

// 设置消息处理函数
func (manager *Manager) SetMessageHandler(handler func([]byte, *Client) error) {
	manager.MessageHandler = handler
}

// 设置获取历史记录函数
func (manager *Manager) SetHistoryHandler(handler func(offset, limit int) ([]Message, error)) {
	manager.HistoryHandler = handler
}

// 设置搜索日期消息处理函数
func (manager *Manager) SetSearchDateHandler(handler func(searchDate string, offset, limit int) ([]Message, error)) {
	manager.SearchDateHandler = handler
}

// 读取客户端消息
func (c *Client) Read() {
	defer func() {
		c.Manager.Unregister <- c
		c.Conn.Close()
	}()

	for {
		_, message, err := c.Conn.ReadMessage()
		if err != nil {
			// 判断是否为正常的连接关闭
			if closeErr, ok := err.(*websocket.CloseError); ok {
				// 根据WebSocket协议，1000表示正常关闭，1005表示无状态关闭（也是正常的）
				if closeErr.Code == websocket.CloseNormalClosure || closeErr.Code == websocket.CloseNoStatusReceived {
					log.Printf("客户端 %s 正常断开连接", c.ID)
				} else {
					log.Printf("客户端 %s 异常关闭: %v", c.ID, err)
				}
			} else {
				// 非关闭类型的错误，记录为错误日志
				log.Printf("读取客户端 %s 消息错误: %v", c.ID, err)
			}
			break
		}

		// 解析消息
		var msg Message
		if err := json.Unmarshal(message, &msg); err != nil {
			log.Printf("解析客户端 %s 消息失败: %v", c.ID, err)
			continue
		}

		var msgList []Message
		switch msg.Type {
		case "get_history":
			msgList, err = c.Manager.HistoryHandler(msg.Offset, msg.Limit)
			if err != nil {
				log.Printf("获取历史记录失败: %v", err)
				continue
			}

			msg.MsgList = msgList
			historyJson, err := json.Marshal(msg)
			if err != nil {
				log.Printf("序列化历史记录失败: %v", err)
				continue
			}

			// 获取历史记录消息
			c.Manager.HistoryPrivate <- historyJson

		case "search_date":
			var searchDateMsg SearchDateMessage
			if err := json.Unmarshal(message, &searchDateMsg); err != nil {
				log.Printf("解析搜索日期消息失败: %v", err)
				continue
			}
			msgList, err := c.Manager.SearchDateHandler(searchDateMsg.Date, searchDateMsg.Offset, searchDateMsg.Limit)
			if err != nil {
				log.Printf("搜索日期消息失败: %v", err)
				continue
			}

			searchDateMsg.MsgList = msgList
			searchDateJson, err := json.Marshal(searchDateMsg)
			if err != nil {
				log.Printf("序列化搜索日期消息失败: %v", err)
				continue
			}

			// 搜索日期消息
			c.Manager.SearchPrivate <- searchDateJson

		case "text":
			// 使用注入的消息处理函数处理消息
			if err := c.Manager.MessageHandler(message, c); err != nil {
				log.Printf("处理客户端 %s 消息错误: %v", c.ID, err)
				continue
			}
			// 根据消息类型处理
			if msg.Recipient != "" {
				// 私有消息
				c.Manager.SendPrivate <- message
			} else {
				// 广播消息
				c.Manager.Broadcast <- message
			}
		default:
			log.Printf("未知消息类型: %s", msg.Type)
		}
	}
}

// 向客户端发送消息
func (c *Client) Write() {
	defer func() {
		c.Conn.Close()
	}()

	for message := range c.Send {
		w, err := c.Conn.NextWriter(websocket.TextMessage)
		if err != nil {
			return
		}
		w.Write(message)

		if err := w.Close(); err != nil {
			return
		}
	}
}
